<template>
  <view class="zzx-calendar">
    <view class="calendar-heander">
      <picker mode="date" fields="month" @change="monthChange">
        <view class="bold">
          <span>{{ timeStr[1] }}</span><span>{{ timeStr[0] }}</span>
          <image src="../../static/img/icon/calendar-down-s.png" mode="widthFix"></image>
        </view>
      </picker>
      <view class="back-today" @click="goback" v-if="showBack"> 返回今日 </view>
    </view>
    <view class="calendar-weeks">
      <view class="calendar-week" v-for="(week, index) in weeks" :key="index">
        {{ week }}
      </view>
    </view>
    <view class="calendar-content" @touchstart="start" @touchend="end">
      <swiper class="calendar-swiper" :style="{
        width: '100%',
        height: sheight,
      }" :indicator-dots="false" :autoplay="false" :duration="duration" :current="current" @change="changeSwp"
        :circular="true">
        <swiper-item class="calendar-item" v-for="sitem in swiper" :key="sitem">
          <view class="calendar-days">
            <template v-if="sitem === current">
              <view class="calendar-day" v-for="(item, index) in days" :key="index" :class="{
                'day-hidden': !item.show,
              }" @click="clickItem(item)">
                <view class="date" :class="[
                  item.isToday ? todayClass : '',
                  item.fullDate === selectedDate ? checkedClass : '',
                ]">
                  {{ item.time.getDate() }}
                </view>
                <view class="dot-show" v-if="item.info" :class="[dotStyleS(item)]">
                </view>
              </view>
            </template>
            <template v-else>
              <template v-if="current - sitem === 1 || current - sitem === -2">
                <view class="calendar-day" v-for="(item, index) in predays" :key="index" :class="{
                  'day-hidden': !item.show,
                }">
                  <view class="date" :class="[item.isToday ? todayClass : '']">
                    {{ item.time.getDate() }}
                  </view>
                </view>
              </template>
              <template v-else>
                <view class="calendar-day" v-for="(item, index) in nextdays" :key="index" :class="{
                  'day-hidden': !item.show,
                }">
                  <view class="date" :class="[item.isToday ? todayClass : '']">
                    {{ item.time.getDate() }}
                  </view>
                </view>
              </template>
            </template>
          </view>
        </swiper-item>
      </swiper>
      <view class="mode-change" @click="changeMode">
        <image :class="weekMode ? 'mode-arrow-bottom' : 'mode-arrow-top'" src="../../static/img/icon/calendar-down.png"
          mode="widthFix"></image>
      </view>
    </view>
  </view>
</template>

<script>
import { gegerateDates, dateEqual, formatDate } from "./generateDates.js";
import util from "../../utils/util";
export default {
  props: {
    duration: {
      type: Number,
      default: 500,
    },
    dot: {
      type: Object,
      default: () => ({
        list: [],
        color: {
          prev: "",
          next: "",
          default: "",
        },
      }),
    },
    showBack: {
      type: Boolean, // 是否返回今日
      default: false,
    },
    todayClass: {
      type: String, // 今日的自定义样式class
      default: "is-today",
    },
    checkedClass: {
      type: String, // 选中日期的样式class
      default: "is-checked",
    },
  },
  watch: {
    "dot.list": function (newvalue) {
      const days = this.days.slice(0);
      newvalue.forEach((item) => {
        const index = days.findIndex((ditem) => ditem.fullDate === item.date);
        if (index > -1) {
          days[index].info = item;
        }
      });
      this.days = days;
    },
  },
  computed: {
    sheight() {
      // 根据年月判断有多少行
      // 判断该月有多少天
      let x = "upx";
      //#ifdef MP-WEIXIN
      x = "rpx";
      //#endif
      let h = `70${x}`;
      if (!this.weekMode) {
        const d = new Date(this.currentYear, this.currentMonth, 0);
        const days = d.getDate(); // 判断本月有多少天
        let day = new Date(d.setDate(1)).getDay();
        if (day === 0) {
          day = 7;
        }
        const pre = 8 - day;
        const rows = Math.ceil((days - pre) / 7) + 1;

        h = 70 * rows + x;
        //#ifdef MP-WEIXIN
        h = 72 * rows + x;
        //#endif
      }
      return h;
    },
    timeStr() {
      let str = "";
      const d = new Date(
        this.currentYear,
        this.currentMonth - 1,
        this.currentDate
      );
      const y = d.getFullYear();
      const m =
        d.getMonth() + 1 <= 9 ? `0${d.getMonth() + 1}` : d.getMonth() + 1;
      str = [`${m}月`, `${y}年`];
      return str;
    },
    predays() {
      let pres = [];
      if (this.weekMode) {
        const d = new Date(
          this.currentYear,
          this.currentMonth - 1,
          this.currentDate
        );
        d.setDate(d.getDate() - 7);
        pres = gegerateDates(d, "week");
      } else {
        const d = new Date(this.currentYear, this.currentMonth - 2, 1);
        pres = gegerateDates(d, "month");
      }
      return pres;
    },
    nextdays() {
      let nexts = [];
      if (this.weekMode) {
        const d = new Date(
          this.currentYear,
          this.currentMonth - 1,
          this.currentDate
        );
        d.setDate(d.getDate() + 7);
        nexts = gegerateDates(d, "week");
      } else {
        const d = new Date(this.currentYear, this.currentMonth, 1);
        nexts = gegerateDates(d, "month");
      }
      return nexts;
    },
    dotStyleS() {
      return item => {
        const nowDate = new Date();
        const afferentDate = new Date(item.fullDate);
        const color = nowDate > afferentDate ? this.dot.color.prev : nowDate < afferentDate ? this.dot.color.next : this.dot.color.default;
        return color.replace('#', '');
      }
    },
  },
  data() {
    return {
      weeks: ["一", "二", "三", "四", "五", "六", "日"],
      current: 1,
      currentYear: "",
      currentMonth: "",
      currentDate: "",
      days: [],
      weekMode: true,
      swiper: [0, 1, 2],
      selectedDate: formatDate(new Date(), "yyyy-MM-dd"),
      startData: { clientX: "", clientY: "" },
      clickState: true,
      time: null,
    };
  },
  methods: {
    changeSwp(e) {
      // console.log(e);
      const pre = this.current;
      const current = e.target.current;
      /* 根据前一个减去目前的值我们可以判断是下一个月/周还是上一个月/周
       *current - pre === 1, -2时是下一个月/周
       *current -pre === -1, 2时是上一个月或者上一周
       */
      this.current = current;
      if (current - pre === 1 || current - pre === -2) {
        this.daysNext();
      } else {
        this.daysPre();
      }
    },
    // 初始化日历的方法
    initDate(cur, mode) {
      let date = "";
      if (cur) {
        date = new Date(cur);
      } else {
        date = new Date();
      }
      this.currentDate = date.getDate(); // 今日日期 几号
      this.currentYear = date.getFullYear(); // 当前年份
      this.currentMonth = date.getMonth() + 1; // 当前月份
      this.currentWeek = date.getDay() === 0 ? 7 : date.getDay(); // 1...6,0   // 星期几

      this.days = [];
      let days = [];
      if (this.weekMode) {
        days = gegerateDates(date, "week");
        // this.selectedDate = days[0].fullDate;
      } else {
        days = gegerateDates(date, "month");
        // const sel = new Date(this.selectedDate.replace('-', '/').replace('-', '/'));
        // const isMonth = sel.getFullYear() === this.currentYear && (sel.getMonth() + 1) === this.currentMonth;
        // if(!isMonth) {
        // 	this.selectedDate = formatDate(new Date(this.currentYear, this.currentMonth-1,1), 'yyyy-MM-dd')
        // }
      }
      days.forEach((day) => {
        const dot = this.dot.list.find((item) => {
          return dateEqual(item.date, day.fullDate);
        });

        if (dot) {
          day.info = dot;
        }
      });
      this.days = days;
      //  派发事件,时间发生改变
      let obj = {
        start: "",
        end: "",
      };
      if (this.weekMode) {
        obj.start = this.days[0].time;
        obj.end = this.days[6].time;
      } else {
        const start = new Date(this.currentYear, this.currentMonth - 1, 1);
        const end = new Date(this.currentYear, this.currentMonth, 0);
        obj.start = start;
        obj.end = end;
      }

      if (mode == "changeMode") {
        return;
      }
      this.selectedDate = `${this.currentYear}-${util.formatNumber(
        this.currentMonth
      )}-${util.formatNumber(this.currentDate)}`
      this.$emit(
        "change",
        `${this.currentYear}-${util.formatNumber(
          this.currentMonth
        )}-${util.formatNumber(this.currentDate)}`
      );
    },
    //  上一个
    daysPre() {
      if (this.weekMode) {
        const d = new Date(
          this.currentYear,
          this.currentMonth - 1,
          this.currentDate
        );
        d.setDate(d.getDate() - 7);
        this.initDate(d);
      } else {
        const d = new Date(this.currentYear, this.currentMonth - 2, 1);
        this.initDate(d);
      }
    },
    //  下一个
    daysNext() {
      if (this.weekMode) {
        const d = new Date(
          this.currentYear,
          this.currentMonth - 1,
          this.currentDate
        );
        d.setDate(d.getDate() + 7);
        this.initDate(d);
      } else {
        const d = new Date(this.currentYear, this.currentMonth, 1);
        this.initDate(d);
      }
    },
    changeMode() {
      const premode = this.weekMode;
      let isweek = false;
      if (premode) {
        isweek = !!this.days.find(
          (item) => item.fullDate === this.selectedDate
        );
      }
      this.weekMode = !this.weekMode;
      let d = new Date(
        this.currentYear,
        this.currentMonth - 1,
        this.currentDate
      );
      const sel = new Date(
        this.selectedDate.replace("-", "/").replace("-", "/")
      );
      const isMonth =
        sel.getFullYear() === this.currentYear &&
        sel.getMonth() + 1 === this.currentMonth;
      if ((this.selectedDate && isMonth) || isweek) {
        d = new Date(this.selectedDate.replace("-", "/").replace("-", "/"));
      }
      this.initDate(d, "changeMode");
    },
    // 点击日期
    clickItem(e) {
      if (this.clickState == false) {
        return false;
      }
      this.selectedDate = e.fullDate;
      this.$emit("change", this.selectedDate);
      this.clickState = false;
      this.time = setTimeout(() => {
        this.clickState = true;
        clearTimeout(this.time);
      }, 500);
    },
    goback() {
      this.selectedDate = new Date().format("Y-m-d");
      this.initDate(new Date());
    },
    monthChange(e) {
      let d = e.detail.value;
      d = d.split("-");
      this.currentYear = d[0];
      this.currentMonth = d[1];
      const f = new Date(
        this.currentYear,
        this.currentMonth - 1,
        this.currentDate
      );
      this.initDate(f);
    },
    start(e) {
      this.startData.clientX = e.changedTouches[0].clientX;
      this.startData.clientY = e.changedTouches[0].clientY;
    },
    end(e) {
      const subX = e.changedTouches[0].clientX - this.startData.clientX;
      const subY = e.changedTouches[0].clientY - this.startData.clientY;
      if (subY > 50 || subY < -50) {
        if (subY > 50) {
          this.weekMode = true;
        } else if (subY < -50) {
          this.weekMode = false;
        }
        this.changeMode();
      }
    },
  },
  created() {
    this.initDate();
  },
  mounted() { },
};
</script>

<style lang="scss" scoped>
.ff2f33 {
  background-color: #ff2f33 !important;
}

.FFB82D {
  background-color: #FFB82D !important;
}

.zzx-calendar {
  width: 100%;
  border-radius: 20upx;
  padding: 10upx 0;
  background: #ffffff;
  height: auto;
  color: rgb(29, 37, 110);

  .calendar-heander {
    // text-align: center;
    padding-left: 30upx;
    height: 60upx;
    line-height: 60upx;
    position: relative;
    font-size: 30upx;

    .back-today {
      position: absolute;
      right: 0;
      padding: 5upx 20upx;
      line-height: 30upx;
      font-size: 20upx;
      top: 15upx;
      border-radius: 15upx 0 0 15upx;
      color: #ffffff;
      background-color: #1ca9ff;
    }
  }

  .calendar-weeks {
    width: 100%;
    display: flex;
    flex-flow: row nowrap;
    height: 60upx;
    line-height: 60upx;
    justify-content: center;
    align-items: center;
    font-size: 20upx;
    font-weight: bold;
    color: #AAAAAA;

    .calendar-week {
      width: calc(100% / 7);
      height: 100%;
      text-align: center;
    }
  }

  .bold {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;

    span {
      font-size: 32upx;
      font-weight: bold;
      color: #333333;
    }

    span:nth-child(1) {
      // font-size: 37upx;
      // margin-right: 10upx;
    }

    span:nth-child(2) {

      margin: 0 10upx;
      // font-size: 27upx;
      // margin-right: 10upx;
    }

    image {
      width: 24upx;
    }
  }

  swiper {
    width: 100%;
    height: 60upx;
  }

  .calendar-content {
    min-height: 60upx;
  }

  .calendar-swiper {
    min-height: 70upx;
    transition: height ease-out 0.3s;
  }

  .calendar-item {
    margin: 0;
    padding: 0;
    height: 100%;
  }

  .calendar-days {
    display: flex;
    flex-flow: row wrap;
    width: 100%;
    height: 100%;
    overflow: hidden;
    font-size: 28upx;

    .calendar-day {
      margin-top: 1upx;
      width: calc(100% / 7);
      height: 70upx;
      text-align: center;
      display: flex;
      flex-flow: column nowrap;
      justify-content: center;
      align-items: center;
      position: relative;
      color: #333333;
    }
  }

  .day-hidden {
    // visibility: hidden;
    // pointer-events: none;
    color: #BBBBBB !important;
  }

  .mode-change {
    display: flex;
    justify-content: center;
    margin-top: 10upx;

    .mode-arrow-top {
      transform: rotate(180deg);
      width: 40upx;
      // height: 10upx;
      // border-radius: 20upx;
      // background: #c7c7c8;
      // border-left: 12upx solid transparent;
      // border-right: 12upx solid transparent;
      // border-bottom: 10upx solid #ff6633;
    }

    .mode-arrow-bottom {
      width: 40upx;
      // height: 10upx;
      // border-radius: 20upx;
      // background: #c7c7c8;
      // border-left: 12upx solid transparent;
      // border-right: 12upx solid transparent;
      // border-top: 10upx solid #ff6633;
    }
  }

  .is-checked {
    color: #ffffff;
    background: linear-gradient(180deg, #1D246A 0%, #1D246A 100%);
    // border: 1upx solid #FF6633;
    // color: #1ca9ff;
  }

  .is-today {
    // background: #1ca9ff;
    // border: 2px solid #1ca9ff;
    color: #1D246A;
  }

  .is-today.is-checked {
    background: linear-gradient(180deg, #1D246A 0%, #1D246A 100%);
    color: #ffffff;
  }

  .is-today.is-checked+.dot-show {
    background: #fff !important;
  }

  .date {
    width: 65upx;
    height: 65upx;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    border-radius: 10upx;
  }

  .dot-show {
    // margin-top: 4upx;
    width: 12upx;
    height: 12upx;
    background: #c6c6c6;
    border-radius: 50%;
    position: absolute;
    bottom: 8upx;
    left: 50%;
    transform: translate(-50%, 0);
  }
}
</style>
